package gui.customizer.panes.netfilter;

import java.io.IOException;
import java.util.HashMap;

import javax.swing.DefaultComboBoxModel;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JTextField;

import net.miginfocom.swing.MigLayout;
import core.models.NatRule;

public class PortForwarding extends NatConfigurable {

	/**
	 * 
	 */
	private static final long serialVersionUID = -304346044641251078L;
	private JTextField txtSource;
	private JTextField txtServerPort;
	private JTextField txtClientAddress;
	private JTextField txtClientPort;
	private JComboBox cmbWanInterface;
	private JCheckBox chckbxSource;
	private JComboBox cmbProtocol;

	/**
	 * Create the panel.
	 */
	public PortForwarding() {
		setLayout(new MigLayout("", "[]20[grow][]", "[][]20[][]20[][]15[]"));
		
		JLabel lblWanInterface = new JLabel("WAN  Interface");
		add(lblWanInterface, "cell 0 0");
		
		JLabel lblSource = new JLabel("Source");
		add(lblSource, "cell 1 0");
		
		cmbWanInterface = new JComboBox();
		add(cmbWanInterface, "cell 0 1,growx");
		try {
			cmbWanInterface.setModel(getAvailableInterfaces());
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		txtSource = new JTextField();
		add(txtSource, "cell 1 1,growx");
		txtSource.setColumns(10);
		
		chckbxSource = new JCheckBox("!");
		add(chckbxSource, "cell 2 1");
		
		JLabel lblProtocol = new JLabel("Protocol");
		add(lblProtocol, "cell 0 2 2 1");
		
		cmbProtocol = new JComboBox();
		add(cmbProtocol, "cell 0 3,growx");
		cmbProtocol.setModel(new DefaultComboBoxModel(new String[] { "tcp", "udp", "-none-" }));
		
		JLabel lblServerPort = new JLabel("Server Port");
		add(lblServerPort, "cell 0 4");
		
		JLabel lblClientAddress = new JLabel("Client Address");
		add(lblClientAddress, "cell 1 4");
		
		JLabel lblClientPort = new JLabel("Client Port");
		add(lblClientPort, "cell 2 4");
		
		txtServerPort = new JTextField();
		add(txtServerPort, "cell 0 5,growx");
		txtServerPort.setColumns(10);
		
		txtClientAddress = new JTextField();
		add(txtClientAddress, "cell 1 5,growx");
		txtClientAddress.setColumns(10);
		
		txtClientPort = new JTextField();
		add(txtClientPort, "cell 2 5,growx");
		txtClientPort.setColumns(10);
		
		btnAdd = new JButton("Add");
		add(btnAdd, "cell 0 6");

	}

	@Override
	public void setRule(NatRule rule) {
		HashMap<String, String> options = rule.getOptions();
		
		// WAN Interface
		if (options.containsKey("-i"))
			cmbWanInterface.setSelectedItem(options.get("-i"));
		else
			cmbWanInterface.setSelectedItem("-none");
		
		// Source
		if (options.containsKey("-s")) {
			txtSource.setText(options.get("-s"));
			chckbxSource.setSelected(false);
		} else if (options.containsKey("! -s")) {
			txtSource.setText(options.get("! -s"));
			chckbxSource.setSelected(true);
		} else {
			txtSource.setText("");
			chckbxSource.setSelected(false);
		}
		
		// Protocol
		if (options.containsKey("-p")) {
			cmbProtocol.setSelectedItem(options.get("-p"));
		} else {
			cmbProtocol.setSelectedItem("-none-");
		}
		
		// Server Port
		if (options.containsKey("-m tcp") || options.containsKey("-m udp")) {
			String value = options.containsKey("-m tcp") ? options.get("-m tcp") : options.get("-m udp");
			String[] elements = value.split(" ");
			if (elements.length == 2 && elements[0].equals("--dport")) {
				txtServerPort.setText(elements[1]);
			}
		} else {
			txtServerPort.setText("");
		}
		
		// Target
		String target[] = options.get("-j").split(" ");
		if (target.length == 3 && target[0].equals("DNAT") && target[1].matches("--to(-destination)?")) {
			String[] addr = target[2].split(":");
			txtClientAddress.setText(addr[0]);
			txtClientPort.setText(addr[1]);
		} else {
			txtClientAddress.setText("");
			txtClientPort.setText("");
		}
	}

	@Override
	public NatRule getRule() {
		NatRule rule = new NatRule("-A", "PREROUTING");

		// WAN Interface
		if (!cmbWanInterface.getSelectedItem().equals("-none-")) {
			rule.addOption("-i", (String) cmbWanInterface.getSelectedItem());
		}
		
		// Source
		if (!txtSource.getText().equals("")) {
			if (chckbxSource.isSelected())
				rule.addOption("! -s", txtSource.getText());
			else
				rule.addOption("-s", txtSource.getText());
		}
		
		// Protocol
		if (!cmbProtocol.getSelectedItem().equals("-none-")) {
			rule.addOption("-p", (String) cmbProtocol.getSelectedItem());
			
			if (!txtServerPort.equals("")) {
				rule.addOption("-m " + (String) cmbProtocol.getSelectedItem(), "--dport " + txtServerPort.getText());
			}
		}
		
		if (!txtClientAddress.equals("") && !txtClientPort.equals("")) {
			rule.addOption("-j", "DNAT --to-destination " + txtClientAddress.getText() + ":" + txtClientPort.getText());
		}
		
		return rule;
	}

	@Override
	public void resetFields() {
		cmbWanInterface.setSelectedItem("-none");
		txtSource.setText("");
		chckbxSource.setSelected(false);
		cmbProtocol.setSelectedItem("tcp");
		txtServerPort.setText("");
		txtClientAddress.setText("");
		txtClientPort.setText("");
	}

}
